home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
asc2bin.c
< prev
next >
Wrap
Text File
|
1995-03-31
|
11KB
|
442 lines
Article 4494 of comp.sys.handhelds:
Path: en.ecn.purdue.edu!noose.ecn.purdue.edu!samsung!usc!zaphod.mps.ohio-state.edu!ub!acsu.buffalo.edu
From: cloos@acsu.buffalo.edu (James H. Cloos)
Newsgroups: comp.sys.handhelds
Subject: Asc2bin and Bin2asc, too.
Message-ID: <61295@eerie.acsu.Buffalo.EDU>
Date: 22 Feb 91 19:49:45 GMT
Sender: news@acsu.Buffalo.EDU
Organization: State University of New York @ Buffalo
Lines: 427
Nntp-Posting-Host: hemingway.acsu.buffalo.edu
Please find below a slightly improved version of asc2bin.c; its improvement
is the ability to create an ASC format file from a hp48sx binary file. To
use it, compile with "cc -g -o asc2bin asc2bin.c" and then, if you machine
is capable of multiple links (all Unix, I understand Amigas, usw.), then
link asc2bin to bin2asc. If not, just copy asc2bin to bin2asc. The
program checks the command name at execution time and chooses which way to
convert from that. (The next improvement would be to make that decission
based on the file's type. Perhaps if it starts with HPHP48- then use
bin2asc option, else use asc2bin option. Maybe I'll even get around to
that sometime [SIGH]....)
I've checked the output of bin2asc vs. hyde.lib, chip225 & its games, and a
few short things I could type in off the 48's screen and into the Sun. (I
can't use ckermit between the workstations and the 48 just now as I get
/usr/spool/locks: permission denied errors; w/ luck that could change in
the future.) **{Excuse the wordiness, bitte.}**
Here is the src:
/*==-==--==---==----==-----==------==------==-----==----==---==--==-==*
* START OF asc2bin.c *
*--=--==--===--====--=====--======--======--=====--====--===--==--=--*/
/*
This programs reads an up to 127K ASCII (RPL) file consisting of a
string intended for ASC-> and converts it into a binary object file.
This program was compiled with Microsoft C 5.1 and Turbo C. ANSI C
conventions are mostly followed.
The original algorithm for CRC computation was extracted from
Li Sheng's posting to comp.sys.handhelds.
01/19/91 PMW created
02/14/91 MAdler modified for portability
15.02.91 JimC added in bin2asc option
*/
#include <stdio.h>
#include <errno.h>
#ifdef __STDC__
# define MODERN
#endif
#ifdef __TURBOC__
# ifndef MODERN
# define MODERN
# endif
#endif
#ifdef MODERN
# include <stdlib.h>
# include <string.h>
# include <ctype.h>
# define FOPR "rb"
# define FOPW "wb"
#else
# define void int
# define size_t unsigned int
extern char *strcat();
extern char *strcpy();
# define FOPR "r"
# define FOPW "w"
#endif
typedef unsigned char BYTE;
typedef unsigned int WORD;
/* Function prototypes for ANSI C */
#ifdef MODERN
int FileExists(char *);
long FileSize(FILE *);
WORD crcBlock(BYTE *, size_t);
void CopyLine(BYTE **, char **, WORD *);
void ReadFile(char *, BYTE **, WORD *);
void WriteFile(char *, BYTE *, WORD );
int main(int, char **);
#endif
#define HEADER_STRING "HPHP48-C"
/* My own version */
#define MAX_READ_SIZE 127
#ifndef FILENAME_MAX
# define FILENAME_MAX 65
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
#ifndef SEEK_END
# define SEEK_END 2
#endif
#ifndef isxdigit
# define isxdigit(c) (c >= '0' && c <= '9' || c >= 'A' && c <= 'F')
#endif
#define HEX2INT(hc) ((unsigned int) (isdigit(hc) ? (hc)-'0' : (hc)-'A'+10))
int FileExists(f)
char *f;
{
FILE *tf;
if ((tf = fopen(f, FOPR)) != NULL) {
fclose(tf);
return 1;
}
else
return 0;
}
long FileSize(f)
FILE *f;
{
long origPos = ftell(f), fileSize = 0;
fseek(f, 0L, SEEK_END);
fileSize = ftell(f);
fseek(f, origPos, SEEK_SET);
return fileSize;
}
#define CALC_CRC(c, i) (((((c)^(i)) & 0xF) * 0x1081) ^ ((c) >> 4))
WORD crcBlock(mb, len)
BYTE *mb;
size_t len;
{
WORD crc = 0, bObjSize = len/2;
while (bObjSize--) {
crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
crc = CALC_CRC(crc, (WORD) ((*mb) >> 4));
++mb;
}
if (len & 1)
crc = CALC_CRC(crc, (WORD) (*mb) & 0xF);
return crc;
}
void CopyLine(mb, s, objSize)
BYTE **mb;
char **s;
WORD *objSize;
{
char *ts = *s;
BYTE *tmb = *mb;
WORD ls = 0;
while (isxdigit(ts[0]) && isxdigit(ts[1])) {
*tmb++ = (BYTE) (HEX2INT(ts[0]) + (HEX2INT(ts[1]) << 4));
ls += 2;
ts += 2;
}
if (isxdigit(ts[0]) && ts[1] == '"') {
/* we ended on a nibble boundary!! */
BYTE crc1, crc2;
/* correct crc by nibble shifting end */
crc2 = (BYTE) ((tmb[-1] >> 4) + (HEX2INT(ts[0]) << 4));
crc1 = (BYTE) ((tmb[-2] >> 4) + ((tmb[-1] & 0xF) << 4));
/* fix memory buffer */
tmb[-2] &= 0xf;
tmb[-1] = crc1;
*tmb++ = crc2;
++ls;
++ts;
}
*s = ts;
*mb = tmb;
*objSize += ls;
}
#define READLN(s, f) fgets((s), sizeof(s), (f))
void ReadFile(filepath, mb, objSize)
char *filepath;
BYTE **mb;
WORD *objSize;
{
FILE *infile;
char lineBuf[250], *p;
WORD bufSize;
long fileSize;
BYTE *wmb;
if (!strchr(filepath, '.'))
strcat(filepath, ".ASC");
if (!(infile = fopen(filepath, "r"))) {
fprintf(stderr, "asc2bin: can't open %s\n", filepath);
exit(EXIT_FAILURE);
}
fileSize = FileSize(infile);
if (fileSize > MAX_READ_SIZE*1024L) {
fprintf(stderr, "asc2bin: File %s is too long\n", filepath);
exit(EXIT_FAILURE);
}
bufSize = 4+(WORD) (fileSize / 2); /* approximate byte size of object */
if (!(*mb = (BYTE *) malloc(bufSize))) {
fprintf(stderr, "asc2bin: Unable to allocate %u bytes\n", bufSize);
exit(EXIT_FAILURE);
}
wmb = *mb;
/* find string */
while (!feof(infile)) {
if (!READLN(lineBuf, infile)) {
if (feof(infile))
fputs("asc2bin: Unable to locate string\n", stderr);
else
perror("asc2bin: Read error");
fclose(infile);
exit(EXIT_FAILURE);
}
if (*lineBuf == '"')
break;
}
*objSize = 0;
/* put string into buffer */
p = &lineBuf[1]; /* skip opening quote */
CopyLine(&wmb, &p, objSize);
/* copy remainder into buffer */
while (*p != '"' && !feof(infile)) {
if (!READLN(lineBuf, infile)) {
if (feof(infile))
fputs("asc2bin: Unable to locate closing quote\n", stderr);
else
perror("asc2bin: Read error");
fclose(infile);
exit(EXIT_FAILURE);
}
p = lineBuf;
CopyLine(&wmb, &p, objSize);
}
fclose(infile);
}
void WriteFile(filepath, mb, objSize)
char *filepath;
BYTE *mb;
WORD objSize;
{
FILE *outfile;
char *extpos = strchr(filepath, '.');
strcpy(extpos+1, "bin");
if (FileExists(filepath)) {
fprintf(stderr, "asc2bin: file already exists: %s\n", filepath);
exit(EXIT_FAILURE);
}
if (!(outfile = fopen(filepath, FOPW))) {
fprintf(stderr, "asc2bin: unable to create %s\n", filepath);
exit(EXIT_FAILURE);
}
fputs(HEADER_STRING, outfile);
while (objSize--)
fputc(*mb++, outfile);
fclose(outfile);
}
int TransBinFile(InFileName, OutFileName)
char *InFileName, *OutFileName;
{
FILE *infile, *outfile;
int count=0, c=0;
WORD bufSize, fileSize, value;
BYTE *bufferStart, *bufferCurrPt, *bp;
int thisisatest=0;
if (strlen(InFileName)) {
if (!(infile = fopen(InFileName,FOPR))) {
fprintf(stderr, "bin2asc: unable to create %s\n",OutFileName);
exit(EXIT_FAILURE);
}
}
else
infile = stdin;
if (strlen(OutFileName)) {
if (!(outfile = fopen(OutFileName,FOPW))) {
fprintf(stderr, "bin2asc: unable to create %s\n",OutFileName);
exit(EXIT_FAILURE);
}
}
else
outfile = stdout;
fileSize = FileSize(infile);
if (fileSize > MAX_READ_SIZE*1024L) {
fprintf(stderr, "bin2asc: File %s is too long\n", InFileName);
exit(EXIT_FAILURE);
}
bufSize = 10+(WORD) (fileSize); /* approximate byte size of object */
if (!(bufferStart = (BYTE *) malloc(bufSize))) {
fprintf(stderr, "bin2asc: Unable to allocate %u bytes\n", bufSize);
exit(EXIT_FAILURE);
}
bufferCurrPt=bufferStart;
fprintf(outfile,"%%%%HP: T(3)A(R)F(.);\n\"");
for (count=8; count>0; count--)
c=getc(infile);
while( (c=getc(infile)) != EOF )
(*(bufferCurrPt++))=c;
value = crcBlock(bufferStart,(size_t)(bufferCurrPt-bufferStart)*2);
*(bufferCurrPt++)=(value & 0x00ff);
*bufferCurrPt=((value & 0xff00) >> 8);
while ((bp=bufferStart++) <= bufferCurrPt) {
fprintf(outfile,"%1.1X%1.1X",(*bp & 0x0f),((*bp & 0xf0) >>4));
if (! (++count % 32))
fprintf(outfile,"\n");
}
thisisatest=1;
fprintf(stderr,"CRC is #%Xh\n",value);
fprintf(outfile,"\"\n");
}
int main(argc, argv)
int argc;
char **argv;
{
char filepath[FILENAME_MAX];
char b2aInFilePath[FILENAME_MAX], b2aOutFilePath[FILENAME_MAX];
BYTE *mb;
WORD objSize, rcrc, crc,bObjSize; /* NOTE: objSize is in nibbles! */
if (! strcmp(*argv,"asc2bin") )
{
if (argc < 2) {
fputs("usage: asc2bin infile[.ext]\n", stderr);
fputs("\treads infile.ext and creates infile.bin\n", stderr);
fputs("\tif omitted, .ext is assumed to be .rpl\n", stderr);
exit(EXIT_FAILURE);
}
strcpy(filepath, argv[1]);
ReadFile(filepath, &mb, &objSize);
if (objSize < 2) {
fputs("asc2bin: String too short to include crc\n", stderr);
exit(EXIT_FAILURE);
}
objSize -= 4; /* nibbles */
bObjSize = objSize / 2 + (objSize & 1);
rcrc = (WORD) mb[bObjSize] + ((WORD) mb[bObjSize+1] << 8);
crc = crcBlock(mb, objSize);
if (crc != rcrc) {
fprintf(stderr,
"asc2bin: Calculated CRC # %Xh does not match read CRC # %Xh\n",
crc, rcrc);
exit(EXIT_FAILURE);
}
WriteFile(filepath, mb, bObjSize);
return EXIT_SUCCESS;
}
else {
if ( argc < 1 )
b2aInFilePath[0] = '\0';
else
strcpy(b2aInFilePath, argv[1]);
if (argc < 2 )
b2aOutFilePath[0] = '\0';
else
strcpy(b2aOutFilePath, argv[2]);
if (!TransBinFile(b2aInFilePath, b2aOutFilePath))
fprintf(stderr,"bin2asc: Tanslation to ASC format unsuccessful.\n");
}
}
/*--=--==--===--====--=====--======--======--=====--====--===--==--=--*
* END OF asc2bin.c *
*==-==--==---==----==-----==------==------==-----==----==---==--==-==*/